package com.nhh.v.service

import java.io.{File, FileWriter}
import java.text.{DecimalFormat, SimpleDateFormat}
import java.util
import java.util.{Date, List}

import com.nhh.v.cons.ServerCons
import com.nhh.v.dto.TownInfo
import com.nhh.v.mapper.{NhhwakCoinDetailsMapper, NhhwakConfigMapper, NhhwakTownsMapper, NhhwakUsersMapper}
import com.nhh.v.model.{NhhwakCoinDetails, NhhwakTowns, NhhwakUsers, TownUserInfo}
import com.nhh.v.utils.{FormatterUtil, NhhUtil}
import org.springframework.beans.BeanUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.StringUtils

import scala.collection.JavaConverters._

/**
  * Created by yuhai.cen on 2018/9/9.
  */
@Service
class TownService(@Autowired val nhhwakTownsMapper: NhhwakTownsMapper,
                  @Autowired val usersMapper: NhhwakUsersMapper,
                  @Autowired val configMapper: NhhwakConfigMapper,
                  @Autowired val coinsDetailMapper: NhhwakCoinDetailsMapper) {

  def getMyTown(uid: Integer, pIndex: Integer, pSize: Integer, townId: Integer): MyTownInfo = {
    var myTown: NhhwakUsers = null
    var town: NhhwakTowns = null
    var townUserCount: Long = 0L
    var townInfo = new TownInfo()
    if (pIndex == 0) {
      town = nhhwakTownsMapper.selectTownById(townId)
      town.setLogo(NhhUtil.getHeadImgUrl(town.getLogo))
      BeanUtils.copyProperties(town, townInfo)
      townInfo.setYtdCoins(NhhUtil.formatNHH(town.getYtdNhhcoins))
      myTown = nhhwakTownsMapper.selectMyTown(uid.toInt)
      myTown.setHeadimgurl(NhhUtil.getHeadImgUrl(myTown.getHeadimgurl))
      myTown.setId(myTown.getTownId)
      //todo need to optimize when there are a lot of users
      townUserCount = nhhwakTownsMapper.selectTownUserCount(myTown.getTownId)
    }
    val config = configMapper.getHashRateConfig
    val townHashRate = config.getTownHashratecoef
    val townUsers = nhhwakTownsMapper.selectTownUsers(townId, townHashRate, pIndex, pSize)
    townUsers.asScala.foreach { user =>
      user.setHeadimgurl(NhhUtil.getHeadImgUrl(user.getHeadimgurl))
      user.setHashrate(FormatterUtil.format(user.getHashrate))
      user.setNhhcoins(NhhUtil.formatNHH(BigDecimal.apply(user.getNhhcoins)))
    }
    MyTownInfo(townInfo, myTown, townUsers, townUserCount)
  }

  def getMeTown(townId: Integer): MeTownInfo = {
    val town = nhhwakTownsMapper.selectTownById(townId)
    town.setLogo(NhhUtil.getHeadImgUrl(town.getLogo))
    MeTownInfo(town)
  }

  def getTowns(uid: Integer, pIndex: Integer, pSize: Integer, order: Integer): GetTowns = {
    var user: NhhwakUsers = null
    if (pIndex == 0) {
      user = usersMapper.selectUserById(uid)
    }
    val towns = new util.ArrayList[TownInfo]()
    val config = configMapper.getHashRateConfig
    val rows = nhhwakTownsMapper.selectTowns(uid, pIndex, pSize, config.getTownHashratecoef)
    rows.asScala.foreach { t =>
      val town = new TownInfo()
      BeanUtils.copyProperties(t, town)
      town.setYtdCoins(NhhUtil.formatNHH(t.getYtdNhhcoins))
      town.setLogo(NhhUtil.getHeadImgUrl(t.getLogo))
      if (StringUtils.isEmpty(t.getCreatetime)) {
        town.setDescription("无")
      }
      town.setHashrateFm(FormatterUtil.format(t.getYtdTotalHashrate))
      towns.add(town)
    }
    return GetTowns(user, towns, pSize)
  }

  @Transactional
  def createTown(uid: Integer, logo: String, townName: String, rate: Integer, description: String): ResultData = {
    if (logo.isEmpty) {
      return new ResultData("-1", "请上传正确的logo")
    }
    if (StringUtils.isEmpty(townName)) {
      return new ResultData("-1", "请设置正确的城池名称")
    }
    if (rate < 0 || rate > 100) {
      return new ResultData("-1", "分红比例异常")
    }
    val file = NhhUtil.base64Decode(logo)
    val fileName = FormatterUtil.dayFormat(System.currentTimeMillis()) + uid + ".png"
    val path = "/uploads/townlogo/" + FormatterUtil.monthFormat(System.currentTimeMillis())
    val uploadDir = new File(ServerCons.BASE_DIR + path)
    val uploadDirX100 = new File(ServerCons.BASE_DIR + path + "x100")
    if (!uploadDir.exists()) {
      uploadDir.createNewFile()
    }
    if (!uploadDirX100.exists()) {
      uploadDirX100.createNewFile()
    }
    val srcFile = new File(ServerCons.BASE_DIR + path + "/" + fileName)
    val fwriter: FileWriter = new FileWriter(srcFile)
    fwriter.write(file)
    NhhUtil.resize(ServerCons.BASE_DIR + path + "/" + fileName,
      ServerCons.BASE_DIR + path + "x100/" + fileName,
      100, 100)
    srcFile.delete()
    val townConsumeCoins = configMapper.getHashRateConfig.getTownConsumeNhhcoins
    if (townConsumeCoins.doubleValue() <= 0) {
      return new ResultData("19005", "配置参数异常！")
    }
    val user = nhhwakTownsMapper.selectMyTown(uid)
    val myTownId = user.getTownId
    val myCoins = user.getNhhcoins.doubleValue()
    if (myTownId != 0) {
      return new ResultData("19003", "您已经加入城池，请先退出！")
    }
    if (myCoins < townConsumeCoins.doubleValue()) {
      return new ResultData("19004", "NHH余额不足！")
    }
    val newTown = new NhhwakTowns()
    newTown.setUserId(uid)
    newTown.setName(townName)
    newTown.setLogo(path + "x100/" + fileName)
    newTown.setRate(new java.math.BigDecimal(rate * 0.01))
    newTown.setDescription(description)
    newTown.setNum(1)
    val newTownId  = nhhwakTownsMapper.createTown(newTown)
    nhhwakTownsMapper.subUserCoins(newTownId, townConsumeCoins, newTown.getId)
    val coinDetail = new NhhwakCoinDetails()
    coinDetail.setUserId(uid)
    coinDetail.setNhhcoins(new java.math.BigDecimal(0 - townConsumeCoins.doubleValue()))
    coinDetail.setRecvtime(new Date())
    coinDetail.setStatus(true)
    coinDetail.setSource("createtown")
    coinDetail.setRelateId(newTown.getId)
    coinsDetailMapper.insert(coinDetail)
    return new ResultData()
  }

  @Transactional
  def updateTown(uid: Integer, logo: String, townName: String, description: String, townId: Integer): ResultData = {
    val myTown = nhhwakTownsMapper.selectMyTown(uid)
    if (myTown.getTownRole != "lord" || myTown.getTownId != townId) {
      return new ResultData("-1", "只允许城主修改自己的城池！")
    }
    if (StringUtils.isEmpty(logo)) {
      return new ResultData("-1", "请上传正确的logo")
    }
    if (logo.length >= 200) {
      val file = NhhUtil.base64Decode(logo)
      val fileName = FormatterUtil.dayFormat(System.currentTimeMillis()) + uid + ".png"
      val path = "/uploads/townlogo/" + FormatterUtil.monthFormat(System.currentTimeMillis())
      val uploadDir = new File(ServerCons.BASE_DIR + path)
      val uploadDirX100 = new File(ServerCons.BASE_DIR + path + "x100")
      if (!uploadDir.exists()) {
        uploadDir.createNewFile()
      }
      if (!uploadDirX100.exists()) {
        uploadDirX100.createNewFile()
      }
      val srcFile = new File(ServerCons.BASE_DIR + path + "/" + fileName)
      val fwriter: FileWriter = new FileWriter(srcFile)
      fwriter.write(file)
      NhhUtil.resize(ServerCons.BASE_DIR + path + "/" + fileName,
        ServerCons.BASE_DIR + path + "x100/" + fileName,
        100, 100)
      srcFile.delete()
      nhhwakTownsMapper.updateTownByTownId(townId, townName, logo, description)
    }
    return new ResultData(retCode = "0", retMsg = "修改成功")
  }

  def joinTown(uid: Integer, townId: Integer): ResultData = {
    if (uid == 0 || townId == 0) {
      return new ResultData("20001", "参数非法")
    }
    val myTown = nhhwakTownsMapper.selectMyTown(uid)
    if (myTown == null) {
      return new ResultData("20003", "用户不存在")
    }
    if (myTown.getTownId != 0) {
      return new ResultData("20004", "您已加入城池!")
    }
    val town = nhhwakTownsMapper.selectTownById(townId)
    if (town == null) {
      return new ResultData("20006", "该城池不存在或者已解散!")
    }
    if (town.getNum >= ServerCons.MAX_TOWN_MNUM) {
      return new ResultData("20008", s"城池人数已到上限${ServerCons.MAX_TOWN_MNUM}")
    }
    val townHashratecoef = configMapper.getHashRateConfig.getTownHashratecoef
    val townHashrate = town.getTempHashrate + town.getNum * townHashratecoef
    nhhwakTownsMapper.updateUserTownByUid(uid, townId)
    nhhwakTownsMapper.updateUserTownCount(townId, 1)
    return new JoinTownResult(town.getNum + 1, townHashrate, FormatterUtil.format(townHashrate))
  }

  def exitTown(uid: Integer, townId: Integer): ResultData = {
    if (uid == 0 || townId == 0) {
      return new ResultData("20001", "参数非法")
    }
    val myTown = nhhwakTownsMapper.selectMyTown(uid)
    if (myTown == null) {
      return new ResultData("20003", "用户不存在")
    }
    if (myTown.getTownId == 0 || myTown.getTownId != townId) {
      return new ResultData("20004", "您没有加入该城池!")
    }
    if (myTown.getTownRole == "lord") {
      nhhwakTownsMapper.dismissTown(townId)
    } else {
      nhhwakTownsMapper.exitTown(uid)
    }
    val town = nhhwakTownsMapper.selectTownById(townId)
    if (town == null) {
      return new ResultData("20006", "该城池不存在或者已解散!")
    }
    val townHashratecoef = configMapper.getHashRateConfig.getTownHashratecoef
    val townHashrate = town.getTempHashrate + town.getNum  * townHashratecoef
    nhhwakTownsMapper.updateUserTownByUid(uid, 0)
    nhhwakTownsMapper.updateUserTownCount(townId, -1)
    val result = new ExitTownResult(town.getNum - 1, townHashrate, FormatterUtil.format(townHashrate))
    result.retMsg = "退出成功"
    return result
  }

  case class ExitTownResult(townNum: Integer, townHashrate: Long, hashrateFm: String) extends ResultData

  case class JoinTownResult(townNum: Integer, townHashrate: Long, hashrateFm: String) extends ResultData

  case class GetTowns(user: NhhwakUsers, rows: List[TownInfo], pSize: Integer) extends ResultData

  case class MeTownInfo(town: NhhwakTowns) extends ResultData

  case class MyTownInfo(town: TownInfo, myTownInfo: NhhwakUsers,
    rows: List[TownUserInfo], usersCount: Long) extends ResultData

}